package com.sduept.nwld.dataserver.controller.assessment;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import com.sduept.bigdata.fault.lbtz.manager.LBTZCaculateManager;
import com.sduept.bigdata.fault.lbtz.model.TransformerShortShockInfo;
import com.sduept.bigdata.fault.transformer.service.TransformerFaultQueryManager;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.model.extend.WaveFile;
import com.sduept.core.dao.SuperDAO;
import com.sduept.nwld.dataserver.util.LibTreeNode;
import com.sduept.utils.DateUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Named
@ViewScoped
public class TransformerFaultController extends AbstractController {


	/**
	 * 变压器运行风险评估
	 */
	private static final long serialVersionUID = 7821174814734718710L;
	String[] items = new String[]{"XA12","XB12","XC12",
			"XA13","XB13","XC13",
			"XA23","XB23","XC23"};
	@Autowired
	private TransformerFaultQueryManager tfqm;
	@Autowired
	private LBTZCaculateManager cM;
	@Autowired
	private SuperDAO dao;

	private TreeNode root;// 根节点
	private TreeNode currentSelect;
	private String currentChartJson;
	private String currentNodeType;

	private Date startDate;
	private Date endDate;

	@PostConstruct
	private void init() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.YEAR,-1);
		startDate = c.getTime();
		endDate = new Date();
		initTree();
	}
	public void initTree() {
		root = new DefaultTreeNode();
		genTreeNode();
	}
	public void query(){
		root.getChildren().clear();
		genTreeNode();
	}
	public void genTreeNode() {
		List<TransformerShortShockInfo> stations = tfqm.getTransformerShortShockInfoGroupStationId(startDate, endDate);
		for(TransformerShortShockInfo s:stations){
			new LibTreeNode("station", s, root);
		}
	}
	public void onNodeExpand(NodeExpandEvent event) {
		TreeNode currentNode = event.getTreeNode();
		if(currentNode.getChildCount()>0){
			return;
		}
		if("station".equals(currentNode.getType())){
			String stationId = ((TransformerShortShockInfo) currentNode.getData()).getStationId();
			List<TransformerShortShockInfo> transformers =tfqm.getTransformerShortShockInfoGroupTransformName(startDate, endDate, stationId);
			for(TransformerShortShockInfo t: transformers){
				new LibTreeNode("transformer",t,currentNode);
			}
		}else if("transformer".equals(currentNode.getType())){
			String stationId = ((TransformerShortShockInfo) currentNode.getData()).getStationId();
			String transformName =((TransformerShortShockInfo) currentNode.getData()).getTransformName();
			List<TransformerShortShockInfo> transformers =tfqm.getTransformerShortShockInfoGroupFaultFileId(startDate, endDate, stationId, transformName);
			for(TransformerShortShockInfo t: transformers){
				new DefaultTreeNode("time",t,currentNode);
			}
		}
	}
	public void onNodeSelect(NodeSelectEvent event) {
		currentSelect = event.getTreeNode();
		currentNodeType = currentSelect.getType();
		TransformerShortShockInfo d = (TransformerShortShockInfo)currentSelect.getData();
		if("time".equals(currentNodeType)){
			List<TransformerShortShockInfo> list =tfqm.getTransformerShortShockInfo(d.getStationId(),d.getTransformName(),d.getFaultFileId());
			for(TransformerShortShockInfo s:list){
				calculateChartJson(s);
			}
			currentChartJson = JSONArray.fromObject(list).toString();
		}
	}
	public void calculateChartJson(TransformerShortShockInfo info){
		//前60.55.50按照原数据。其他按照向前推数据。

		Class<TransformerShortShockInfo> c = TransformerShortShockInfo.class;
		String gpre = "getPreShortReactance";
		String spre = "setPreShortReactance";
		String gpost = "getPostShortReactance";
		String spost = "setPostShortReactance";
		List<Double[]> values = new ArrayList<>();
		for(int j=180;j>=0;j=j-5){
			Method m = null;
			Object value = null;
			try {
				m = c.getMethod(gpost+j);
			} catch (NoSuchMethodException | SecurityException e) {
				e.printStackTrace();
			}
			try {
				value = m.invoke(info);
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
			values.add( fromJsonToDouble(value));
		}
		for(int j=20;j<=60;j=j+5){
			Method m = null;
			Object value = null;
			try {
				m = c.getMethod(gpre+j);
			} catch (NoSuchMethodException | SecurityException e) {
				e.printStackTrace();
			}
			try {
				value = m.invoke(info);
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
			values.add( fromJsonToDouble(value));
		}
		for(int i=0;i<37;i++){
			List<Double[]> rs = new ArrayList<>();
			for(int j=i;j<i+4;j++){
				rs.add(values.get(j));
			}
			JSONObject valueJson = fromDoubleToJson(average(rs));
			Method m = null;
			try {
				m = c.getMethod(spost+(180-i*5), String.class);
			} catch (NoSuchMethodException | SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				m.invoke(info, valueJson.toString());
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		for(int i = 37;i<values.size()-3;i++){
			List<Double[]> rs = new ArrayList<>();
			for(int j=i;j<i+4;j++){
				rs.add(values.get(j));
			}
			JSONObject valueJson = fromDoubleToJson(average(rs));
			Method m = null;
			try {
				m = c.getMethod(spre+(20+(i-37)*5), String.class);
			} catch (NoSuchMethodException | SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			try {
				m.invoke(info, valueJson.toString());
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	private JSONObject fromDoubleToJson(String[] d){
		JSONObject j = new JSONObject();
		for(int i=0;i<items.length;i++){
			j.put(items[i], d[i]);
		}
		return j;
	}
	private Double[] fromJsonToDouble(Object o){
		JSONObject jsono = JSONObject.fromObject(o);
		Double[] result = new Double[9];
		for(int i=0;i<items.length;i++){
			Object j = jsono.get(items[i]);
			Double value = null;
			if(j != null){
				value = Double.parseDouble(j.toString());
			}
			result[i] = value;
		}
		return result;
	}

	private String[] average(List<Double[]> list){
		String[] result = new String[9];
		DecimalFormat df = new DecimalFormat("#0.000");
		for(int i=0;i<9;i++){
			//检测阻抗是否未空。
			if(list.get(0)[i] != null){
				double v=0;
				for(Double[] ff:list){
					v +=ff[i];
				}
				result[i] = df.format(v/list.size());
			}else{
				result[i] = null;
			}
		}
		return result;
	}

	/**
	 * 手动更新
	 */
	public void manualUpdate() {

		String startStr = DateUtil.getStringDate(startDate, DateUtil.pattern_ymd000);
		String endStr = DateUtil.getStringDate(endDate, DateUtil.pattern_ymd235959);
		List<WaveFile> wlist  = dao.findByCondition(WaveFile.class, "triggerSecond>=? AND triggerSecond<=?", startStr,endStr);
		List<TransformerShortShockInfo> shockInfo = dao.findByCondition(TransformerShortShockInfo.class, "faultTime>=? AND faultTime<=?", startStr,endStr);
		Set<String> fileIds = new HashSet<>();
		shockInfo.forEach(info -> {fileIds.add(info.getId()); });
		for (WaveFile waveFile : wlist) {
			if(!fileIds.contains(waveFile.getId())) {
				cM.caculateTransformerFaultShortShock(waveFile.getId(), 1);
			}
		}



	}


	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public TreeNode getCurrentSelect() {
		return currentSelect;
	}
	public void setCurrentSelect(TreeNode currentSelect) {
		this.currentSelect = currentSelect;
	}
	public String getCurrentChartJson() {
		return currentChartJson;
	}
	public void setCurrentChartJson(String currentChartJson) {
		this.currentChartJson = currentChartJson;
	}
	public Date getStartDate() {
		return startDate;
	}
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}
	public Date getEndDate() {
		return endDate;
	}
	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}
	public String getCurrentNodeType() {
		return currentNodeType;
	}
	public void setCurrentNodeType(String currentNodeType) {
		this.currentNodeType = currentNodeType;
	}

}
